# coding=utf-8
# -*- coding: utf-8 -*-
import pickle
import sys
import matplotlib
import pandas as pd

if sys.version > '3':
    PY3 = True
else:
    PY3 = False
print("PY3:" + str(PY3))


class Store(dict):
    """
    自定义存储Map，去除空key情况下的错误问题
    """

    def __missing__(self, key):
        self[key] = {}
        return self[key]


# 输入端口内容
in_values = Store()
# 输出端口内容
out_values = Store()
# 节点配置参数
node_parameters = Store()
# 输入端口图片数据
in_img_values = Store()
# 输出端口图片数据
out_img_values = Store()
# 模型输入口内容
in_model_values = Store()
# 模型输出口内容
out_model_values = Store()
# 结果集输入口内容
in_result_set_values = Store()
# 结果集输出口内容
out_result_set_values = Store()

"""
设置输入端口数据
"""


def setInPortValue(code, value):
    if isinstance(code, str):
        in_values[code] = value
    else:
        raise ValueError(f"code类型不正确，需要是str")

    if type(value) is pd.DataFrame:
        in_values[code] = value
    else:
        raise ValueError(f"类型不正确，需要是pandas.core.frame.DataFrame")


"""
获取输入端口数据
"""


def getInPortValue(code):
    if code in in_values:
        return in_values[code]
    else:
        return None


"""
设置输出端口数据
"""


def setOutPortValue(code, value):
    if isinstance(code, str):
        out_values[code] = value
    else:
        raise ValueError(f"code类型不正确，需要是str")

    if type(value) is pd.DataFrame:
        out_values[code] = value
    else:
        raise ValueError(f"value类型不正确，需要是pandas.core.frame.DataFrame")


"""
获取输出端口数据
"""


def getOutPortValue(code):
    if code in out_values:
        return out_values[code]
    else:
        return None


"""
设置配置参数
"""


def setParameter(key, value):
    if not isinstance(key, str):
        raise ValueError(f"key类型不正确，需要是str")
    node_parameters[key] = value


"""
设置配置参数
"""


def setParameters(parameters):
    if type(parameters) is dict:
        for key in parameters:
            setParameter(key, parameters[key])
    else:
        raise ValueError("参数parameters必须为字典（dict）类型，请处理！")


"""
根据key获取配置参数
"""


def getParameter(key):
    return node_parameters[key]


"""
获取配置参数
"""


def getParameters():
    return node_parameters


"""
保存图片
"""


def saveNodeImage(code, fig):
    if not isinstance(code, str):
        raise ValueError(f"code类型不正确，需要是str")

    if type(fig) != matplotlib.figure.Figure:
        raise ValueError("fig参数的类型不是matplotlib.figure.Figure！")


"""
设置输出端口图数据
"""


def setOutPortImageValue(code, x_data, y_data=None):
    if not isinstance(code, str):
        raise ValueError(f"code类型不正确，需要是str")

    if type(x_data) is not list:
        raise ValueError("参数x_data必须为列表（list）类型，请处理！")

    if y_data is not None and not isinstance(y_data, list):
        raise ValueError("参数y_data必须为列表（list）类型，请处理！")

    img_data = out_img_values.setdefault(code, {})
    img_data['x_data'] = x_data

    if y_data is not None:
        img_data['y_data'] = y_data


"""
获取输出端口图数据
"""


def getOutPortImageValue(code):
    if not isinstance(code, str):
        raise ValueError(f"code类型不正确，需要是str")

    if code in out_img_values:
        result = out_img_values[code]
        return result.get('x_data'), result.get('y_data')
    else:
        return None


"""
获取输入端口图数据
"""


def getInPortImageValue(code):
    if not isinstance(code, str):
        raise ValueError(f"code类型不正确，需要是str")

    if code in in_img_values:
        result = in_img_values[code]
        return result.get('x_data'), result.get('y_data')
    else:
        return None


"""
设置输入端口图数据
"""


def setInPortImageValue(code, x_data, y_data=None):
    if not isinstance(code, str):
        raise ValueError(f"code类型不正确，需要是str")

    if type(x_data) is not list:
        raise ValueError("参数x_data必须为列表（list）类型，请处理！")

    if y_data is not None and not isinstance(y_data, list):
        raise ValueError("参数y_data必须为列表（list）类型，请处理！")

    img_data = in_img_values.setdefault(code, {})
    img_data['x_data'] = x_data

    if y_data is not None:
        img_data['y_data'] = y_data


"""
设置模型输入端口数据
"""


def setInPortModelValue(code, estimator):
    if not isinstance(code, str):
        raise ValueError(f"code类型不正确，需要是str")

    in_model_values[code] = pickle.dumps(estimator)


"""
获取模型输入端口数据
"""


def getInPortModelValue(code):
    if not isinstance(code, str):
        raise ValueError(f"code类型不正确，需要是str")

    if code in in_model_values:
        result = in_model_values[code]
        return pickle.loads(result)
    else:
        return None


"""
设置模型输出端口数据
"""


def setOutPortModelValue(code, estimator):
    if not isinstance(code, str):
        raise ValueError(f"code类型不正确，需要是str")

    out_model_values[code] = pickle.dumps(estimator)


"""
获取模型输出端口数据
"""


def getOutPortModelValue(code):
    if not isinstance(code, str):
        raise ValueError(f"code类型不正确，需要是str")

    if code in out_model_values:
        result = out_model_values[code]
        return pickle.loads(result)
    else:
        return None


"""
设置结果集输入端口数据
"""


def setInPortResultSetValue(code, result_set):
    if not isinstance(code, str):
        raise ValueError(f"code类型不正确，需要是str")

    in_result_set_values[code] = pickle.dumps(result_set)


"""
获取结果集输入端口数据
"""


def getInPortResultSetValue(code):
    if not isinstance(code, str):
        raise ValueError(f"code类型不正确，需要是str")

    if code in in_result_set_values:
        result = in_result_set_values[code]
        return pickle.loads(result)
    else:
        return None


"""
设置结果集输出端口数据
"""


def setOutPortResultSetValue(code, result_set):
    if not isinstance(code, str):
        raise ValueError(f"code类型不正确，需要是str")

    out_result_set_values[code] = pickle.dumps(result_set)


"""
获取结果集输出端口数据
"""


def getOutPortResultSetValue(code):
    if not isinstance(code, str):
        raise ValueError(f"code类型不正确，需要是str")

    if code in out_result_set_values:
        result = out_result_set_values[code]
        return pickle.loads(result)
    else:
        return None


"""
打印输出信息
"""
def consoleLog(info):
    print(str(info))


"""
设置显示效果，参数如下：
    {
        "eval_result": {
            "准确率": 9.99,
        }
    }
"""
def setShowData(show_data):
    if type(show_data) is not dict:
        raise ValueError(f"参数必须是字典类型")
